package model.notes;

import model.notes.impl.NoteImpl;

public interface Note {

	public static final Note DO = new NoteImpl(NoteName.DO);
	public static final Note RE = new NoteImpl(NoteName.RE);
	public static final Note MI = new NoteImpl(NoteName.MI);
	public static final Note FA = new NoteImpl(NoteName.FA);
	public static final Note SOL = new NoteImpl(NoteName.SOL);
	public static final Note LA = new NoteImpl(NoteName.LA);
	public static final Note SI = new NoteImpl(NoteName.SI);

	
	public static enum NoteName {
		DO (0, "Do"),
		RE (1, "Ré"),
		MI (2, "Mi"),
		FA (2.5, "Fa"),
		SOL (3.5, "Sol"),
		LA (4.5, "La"),
		SI (5.5, "Si");
		
		private double tonality;
		private String str;
		
		NoteName(double tonality, String str) {
			this.tonality = tonality;
			this.str = str;
		}
		
		public double getTonality() {
			return this.tonality;
		}
		
		public String toString() {
			return this.str;
		}
		
		public static NoteName valueOf(double tonality) {
			NoteName result = null;
			int doubleTonality = (int) (2*tonality);
			switch (doubleTonality) {
			case 0 : 
				result = NoteName.DO;
				break;
			case 2 : 
				result = NoteName.RE;
				break;
			case 4 : 
				result = NoteName.MI;
				break;
			case 5 : 
				result = NoteName.FA;
				break;
			case 7 : 
				result = NoteName.SOL;
				break;
			case 9 : 
				result = NoteName.LA;
				break;
			case 11 : 
				result = NoteName.SI;
				break;
			}
			return result;
		}
	}
	
	public static enum InternationalNoteName {
		C,
		D,
		E,
		F,
		G,
		A,
		B
	}
	
	public static enum NoteValue {
		RONDE (4),
		BLANCHE (2),
		NOIRE (1),
		CROCHE (0.5),
		DOUBLE_CROCHE (0.25);
		
		private double value;
		
		NoteValue (double value) {
			this.value = value;
		}
		
		public double getValue() {
			return this.value;
		}
	}
	
	public static enum NoteAlteration {
		NO_ALTERATION (0, ""),
		DIESE (0.5, "#"),
		BEMOL (-0.5, "b");
		
		private double tonality;
		private String str;
		
		NoteAlteration(double tonality, String str) {
			this.tonality = tonality;
			this.str = str;
		}
		
		public double getTonality() {
			return this.tonality;
		}
		
		public String toString() {
			return this.str;
		}
	}
	
	public NoteName getName();
	
	public InternationalNoteName getInternationalName(); 
	
	public NoteValue getValue();
	
	public NoteAlteration getAlteration();
	
	public String toString();

	public Note getSecondeMineure(boolean alterWithDiese);
	
	public Note getSecondeMajeure(boolean alterWithDiese);
	
	public Note getTierceMineure(boolean alterWithDiese);
	
	public Note getTierceMajeure(boolean alterWithDiese);
	
	public Note getQuarte(boolean alterWithDiese);
	
	public Note getQuinteMineure(boolean alterWithDiese);
	
	public Note getQuinte(boolean alterWithDiese);
	
	public Note getQuinteMajeure(boolean alterWithDiese);
	
	public Note getSixte(boolean alterWithDiese);
	
	public Note getSeptiemeMineure(boolean alterWithDiese);
	
	public Note getSeptiemeMajeure(boolean alterWithDiese);
	
	public double getTonality();
	
	public Note[] getGammeMajeure();
	
	public Note[] getGammeMineure();
}
